基于Vue快速实现列表拖拽排序

您所在的位置:网站首页 vue list合并 基于Vue快速实现列表拖拽排序

基于Vue快速实现列表拖拽排序

2023-09-09 19:57| 来源: 网络整理| 查看: 265

前言

在业务中列表拖拽排序是比较常见的需求,常见的JS拖拽库有Sortable.js,Vue.Draggable等,大多数同学遇到这种需求也是更多的求助于这些JS库,其实,使用HTML原生的拖放事件来实现拖拽排序并不复杂,结合Vue的transition-group,还能快速的给排序添加过渡动画。

demo

HTML5拖放API 设置元素为可拖放

让一个元素能被拖放需要设置 draggable 属性为true(文本、图片和链接的draggable默认就是true)

能被拖放的元素 拖放事件

拖放涉及到两种元素,一种是被拖拽元素(源对象),一种是放置区元素(目标对象)。如下图所示,按住A元素往B元素拖拽,A元素即为源对象,B元素即为目标对象。

image-20201223092700804

不同的对象产生不同的拖放事件。

触发对象事件名称说明源对象dragstart源对象开始被拖动时触发drag源对象被拖动过程中反复触发dragend源对象拖动结束时触发目标对象dragenter源对象开始进入目标对象范围内触发dragover源对象在目标对象范围内移动时触发dragleave源对象离开目标对象范围时触发drop源对象在目标对象范围内被释放时触发

需要注意的是:dragenter和dragover事件的默认行为是拒绝接受任何被拖放的元素。因此,我们要在这两个拖放事件中使用preventDefault来阻止浏览器的默认行为;而且目标对象想要变成可释放区域,必须设置dragover 和 drop 事件处理程序属性。

拖放还有其他一些属性和方法,但对于我们今天要实现的效果,只需要掌握上面提到的这些属性和方法就可以了,如果你想深入探究,可以参考HTML拖放API

拖拽排序

下面我们利用拖放API来实现列表的拖拽排序,代码基于Vue实现。

先不考虑排序动画。代码并不复杂,就全部贴了出来,然后解释一下实现思路:

由于拖动是实时的,所以没有使用drop而是使用了dragenter触发排序。 在源对象开始被拖拽时记录其索引dragIndex,当它进入目标对象时(对应dragenter事件),将其插入到目标对象的位置。 其中dragenter方法中有一个判断this.dragIndex !== index(index为当前目标对象的索引),这是因为源对象同时也是目标对象,当没有这个判断时,源对象开始被拖拽时就会立刻触发自身的dragenter事件,这是不合理的。

最终效果如下图所示:

demo

{{item.label}} export default { data() { return { list: [ { label: '列表1' }, { label: '列表2' }, { label: '列表3' }, { label: '列表4' }, { label: '列表5' }, { label: '列表6' }, ], dragIndex: '', enterIndex: '', }; }, methods: { dragstart(index) { this.dragIndex = index; }, dragenter(e, index) { e.preventDefault(); // 避免源对象触发自身的dragenter事件 if (this.dragIndex !== index) { const source = this.list[this.dragIndex]; this.list.splice(this.dragIndex, 1); this.list.splice(index, 0, source); // 排序变化后目标对象的索引变成源对象的索引 this.dragIndex = index; } }, dragover(e, index) { e.preventDefault(); }, }, }; .list { list-style: none; .list-item { cursor: move; width: 300px; background: #EA6E59; border-radius: 4px; color: #FFF; margin-bottom: 6px; height: 50px; line-height: 50px; text-align: center; } }

减去HTML和CSS,核心的dragenter只有不超过15行的代码,就可实现一个拖拽排序功能。当然这个拖拽效果有点生硬,下面使用Vue自带的transition-group组件,给排序添加平滑的过渡效果。

排序动画

如果不熟悉Vue的transition-group,请先学习Vue的列表的排序过渡,这里不再赘述。

为了便于和上面的代码进行比较,同样一次性把全部代码贴出,可以看到代码变动并不大,只需把HTML的ul元素改为transition-group,在methods中新增shuffle方法,在CSS中新增一个过渡transition: transform .3s;即可实现开头第一张图所展示的拖拽排序效果了。

你可以点击此链接进行在线体验。

{{item.label}} export default { data() { return { list: [ { label: '列表1' }, { label: '列表2' }, { label: '列表3' }, { label: '列表4' }, { label: '列表5' }, { label: '列表6' }, ], dragIndex: '', enterIndex: '', }; }, methods: { shuffle() { this.list = this.$shuffle(this.list); }, dragstart(index) { this.dragIndex = index; }, dragenter(e, index) { e.preventDefault(); // 避免源对象触发自身的dragenter事件 if (this.dragIndex !== index) { const moving = this.list[this.dragIndex]; this.list.splice(this.dragIndex, 1); this.list.splice(index, 0, moving); // 排序变化后目标对象的索引变成源对象的索引 this.dragIndex = index; } }, dragover(e, index) { e.preventDefault(); }, }, }; .list { list-style: none; .drag-move { transition: transform .3s; } .list-item { cursor: move; width: 300px; background: #EA6E59; border-radius: 4px; color: #FFF; margin-bottom: 6px; height: 50px; line-height: 50px; text-align: center; } }

如果想使用原生JS实现列表的拖拽排序和过渡动画,可以参考这篇文章:js drag拖动排序



【本文地址】


今日新闻


推荐新闻


    CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3